from pydantic import BaseModel, validator, Field
from typing import Optional, List, Dict
from decimal import Decimal
from datetime import datetime


class ProductCreate(BaseModel):
    """商品创建验证器"""
    name: str
    description: Optional[str] = None
    price: float
    category_id: int
    template_3d_url: Optional[str] = None
    default_material: Optional[str] = None
    available_materials: Optional[List[str]] = None
    stock_quantity: int = 0
    
    @validator('name')
    def validate_name(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('商品名称不能为空')
        if len(v) > 200:
            raise ValueError('商品名称长度不能超过200个字符')
        return v.strip()
    
    @validator('price')
    def validate_price(cls, v):
        if v <= 0:
            raise ValueError('商品价格必须大于0')
        if v > 999999.99:
            raise ValueError('商品价格不能超过999999.99')
        return round(v, 2)
    
    @validator('category_id')
    def validate_category_id(cls, v):
        if v <= 0:
            raise ValueError('分类ID必须大于0')
        return v
    
    @validator('stock_quantity')
    def validate_stock_quantity(cls, v):
        if v < 0:
            raise ValueError('库存数量不能为负数')
        return v


class ProductUpdate(BaseModel):
    """商品更新验证器"""
    name: Optional[str] = None
    description: Optional[str] = None
    price: Optional[float] = None
    category_id: Optional[int] = None
    template_3d_url: Optional[str] = None
    default_material: Optional[str] = None
    available_materials: Optional[List[str]] = None
    is_active: Optional[bool] = None
    stock_quantity: Optional[int] = None
    
    @validator('name')
    def validate_name(cls, v):
        if v is not None:
            if not v or len(v.strip()) == 0:
                raise ValueError('商品名称不能为空')
            if len(v) > 200:
                raise ValueError('商品名称长度不能超过200个字符')
            return v.strip()
        return v
    
    @validator('price')
    def validate_price(cls, v):
        if v is not None:
            if v <= 0:
                raise ValueError('商品价格必须大于0')
            if v > 999999.99:
                raise ValueError('商品价格不能超过999999.99')
            return round(v, 2)
        return v
    
    @validator('stock_quantity')
    def validate_stock_quantity(cls, v):
        if v is not None:
            if v < 0:
                raise ValueError('库存数量不能为负数')
            return v
        return v


class ProductImageUpload(BaseModel):
    """商品图片上传验证器"""
    product_id: int
    is_primary: bool = False
    
    @validator('product_id')
    def validate_product_id(cls, v):
        if v <= 0:
            raise ValueError('商品ID必须大于0')
        return v


class CategoryCreate(BaseModel):
    """分类创建验证器"""
    name: str
    description: Optional[str] = None
    image_url: Optional[str] = None
    sort_order: int = 0
    
    @validator('name')
    def validate_name(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('分类名称不能为空')
        if len(v) > 100:
            raise ValueError('分类名称长度不能超过100个字符')
        return v.strip()
    
    @validator('sort_order')
    def validate_sort_order(cls, v):
        if v < 0:
            raise ValueError('排序值不能为负数')
        return v


class CategoryUpdate(BaseModel):
    """分类更新验证器"""
    name: Optional[str] = None
    description: Optional[str] = None
    image_url: Optional[str] = None
    sort_order: Optional[int] = None
    is_active: Optional[bool] = None
    
    @validator('name')
    def validate_name(cls, v):
        if v is not None:
            if not v or len(v.strip()) == 0:
                raise ValueError('分类名称不能为空')
            if len(v) > 100:
                raise ValueError('分类名称长度不能超过100个字符')
            return v.strip()
        return v
    
    @validator('sort_order')
    def validate_sort_order(cls, v):
        if v is not None:
            if v < 0:
                raise ValueError('排序值不能为负数')
            return v
        return v


class Model3DCreate(BaseModel):
    """3D模型创建验证器"""
    product_id: int
    source_image_id: int
    model_file_url: str
    file_format: str
    preview_image_url: Optional[str] = None
    parameters: Optional[Dict] = None
    ai_model_used: Optional[str] = None
    generation_time: Optional[int] = None
    
    @validator('product_id', 'source_image_id')
    def validate_id(cls, v):
        if v <= 0:
            raise ValueError('ID必须大于0')
        return v
    
    @validator('model_file_url')
    def validate_model_file_url(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('模型文件URL不能为空')
        return v.strip()
    
    @validator('file_format')
    def validate_file_format(cls, v):
        allowed_formats = ['glb', 'gltf', 'obj', 'stl', 'fbx', 'dae']
        if v.lower() not in allowed_formats:
            raise ValueError(f'不支持的文件格式，支持的格式: {", ".join(allowed_formats)}')
        return v.lower()
    
    @validator('generation_time')
    def validate_generation_time(cls, v):
        if v is not None and v < 0:
            raise ValueError('生成时间不能为负数')
        return v


class ProductResponse(BaseModel):
    """商品响应模型"""
    id: int
    name: str
    description: Optional[str]
    price: float
    category_id: int
    template_3d_url: Optional[str]
    default_material: Optional[str]
    available_materials: Optional[List[str]]
    is_active: bool
    stock_quantity: int
    created_at: datetime
    updated_at: datetime
    
    class Config:
        orm_mode = True
        json_encoders = {
            datetime: lambda v: v.isoformat() if v else None
        }